﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CallCenter.Data.BizUtilities.Base
{

    public class DataColumnType
    {
        public string Name { get; set; }
        public Type Type { get; set; }
    }
   public static class CommonUtility
    {
        public static IEnumerable<DataColumnType> GetIntersectColumns<T>(DataColumnCollection columns) where T : new()
        {
            const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
            var objFieldNames = (from PropertyInfo aProp in typeof(T).GetProperties(flags)
                                 select new DataColumnType()
                                 {
                                     Name = aProp.Name,
                                     Type = Nullable.GetUnderlyingType(aProp.PropertyType) ?? aProp.PropertyType
                                 });
            var dataTblFieldNames = (from DataColumn aHeader in columns
                                     select new DataColumnType()
                                     {
                                         Name = aHeader.ColumnName,
                                         Type = aHeader.DataType
                                     });
            foreach (var column in dataTblFieldNames)
                if (objFieldNames.Any(c => c.Name == column.Name))
                {
                    var selectedColumn = objFieldNames.FirstOrDefault(c => c.Name == column.Name);
                    yield return selectedColumn;
                }

            //return objFieldNames.Intersect(dataTblFieldNames).ToList();
        }

        public static List<TSource> ToListNew<TSource>(this DataTable dataTable) where TSource : new()
        {
            var dataList = new List<TSource>();

            var commonFields = CommonUtility.GetIntersectColumns<TSource>(dataTable.Columns);

            foreach (DataRow dataRow in dataTable.AsEnumerable().ToList())
            {
                var aTSource = CommonUtility.ToSource<TSource>(dataRow, commonFields.ToList());
                dataList.Add(aTSource);
            }
            return dataList;
        }

        public static TSource ToSource<TSource>(this DataRow row, List<DataColumnType> commonFields) where TSource : new()
        {
            var aTSource = new TSource();
            foreach (var aField in commonFields)
            {
                PropertyInfo propertyInfos = aTSource.GetType().GetProperty(aField.Name);
                var value = (row[aField.Name] == DBNull.Value) ?
                null : row[aField.Name]; //if database field is nullable
               propertyInfos.SetValue(aTSource, value, null);
            }

            return aTSource;
        }

        public static TSource ToSource<TSource>(this DataRow row) where TSource : new()
        {
            var commonFields = CommonUtility.GetIntersectColumns<TSource>(row.Table.Columns);
            return CommonUtility.ToSource<TSource>(row, commonFields.ToList());
        }
    }
}
